package org.levi.demo.thread;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.threadpool.support.fixed.FixedThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.*;

public class MyDubboThread extends FixedThreadPool implements Runnable {

    private static final Logger LOG = LoggerFactory.getLogger(MyDubboThread.class);

    private static final double MAX_RATE = 0.9;
    private static final Map<URL, ThreadPoolExecutor> THREAD_POOL_EXECUTOR_MAP = new ConcurrentHashMap<>();

    public MyDubboThread() {
        //实例化的时候就启动一个线程去定时上报统计时间
        Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(this, 1000, 3000, TimeUnit.MILLISECONDS);
    }

    @Override
    public Executor getExecutor(URL url) {
        final Executor executor = super.getExecutor(url);
        if(executor instanceof ThreadPoolExecutor){
            THREAD_POOL_EXECUTOR_MAP.put(url, (ThreadPoolExecutor) executor);
        }
        return executor;
    }

    public void run() {

        for(Map.Entry<URL,ThreadPoolExecutor> entry:THREAD_POOL_EXECUTOR_MAP.entrySet()){

            final URL urlKey = entry.getKey();
            final ThreadPoolExecutor currentThreadPool = entry.getValue();

            final int activeCount = currentThreadPool.getActiveCount();
            final int poolSize = currentThreadPool.getCorePoolSize();
            if(activeCount == 0){
                LOG.info("---当前无客户端消费，没有执行中的线程---");
                return;
            }
            double usePercent = activeCount/(poolSize*1.0) * 100;
            LOG.info("线程池执行状态[{}/{}:{}%]",activeCount,poolSize,usePercent);
            if(usePercent > MAX_RATE * 100){
                LOG.warn("超出警戒线了，当前Host:{}.当前使用率是[{}],URL是{}",urlKey.getIp(),usePercent,urlKey);
            }
        }
    }
}
